חקור את התפקיד הקריטי של בוררים מאובטחי טיפוס ויישום סוג הזרמת אירועים בבניית מערכות מבוזרות גלובליות חזקות, ניתנות להרחבה וקלות לתחזוקה.
בוררים מאובטחי טיפוס: שליטה ביישום סוג הזרמת אירועים למערכות גלובליות
בנוף המורכב של מערכות מבוזרות מודרניות, היכולת להחליף מידע בין שירותים בצורה מהימנה היא בעלת חשיבות עליונה. בוררי הודעות ופלטפורמות הזרמת אירועים משמשים כעמוד השדרה של תקשורת זו, ומאפשרים אינטראקציות אסינכרוניות, ניתוק שירותים והקלת מדרגיות. עם זאת, ככל שמערכות גדלות במורכבות ובהפצה גיאוגרפית, צץ אתגר קריטי: הבטחת בטיחות הסוג של האירועים המוחלפים. כאן יישום סוג הזרמת אירועים חזק הופך לא רק לנוהג מומלץ, אלא לצורך לבניית יישומים גמישים, ניתנים לתחזוקה ועקביים מבחינה גלובלית.
מדריך מקיף זה מתעמק בעולם של בוררי הודעות מאובטחי טיפוס, בוחן מדוע זה חיוני, האתגרים הנפוצים בהם נתקלים ואסטרטגיות היישום והטכנולוגיות המובילות הזמינות למפתחים ברחבי העולם. ננווט בניואנסים של הגדרה, ניהול ואכיפה של סוגי נתונים בתוך זרמי אירועים, ונעצים אותך לבנות מערכות מבוזרות אמינות וצפויות יותר.
הצו של בטיחות סוג בהזרמת אירועים
תארו לעצמכם פלטפורמת מסחר אלקטרוני גלובלית שבה מיקרו-שירותים שונים מטפלים בכל דבר, החל מניהול קטלוג מוצרים ועד מילוי הזמנות ותמיכת לקוחות. שירותים אלה מתקשרים על ידי פרסום והרשמה לאירועים. ללא בטיחות סוג, שירות עשוי לפרסם אירוע עם שדה price כמחרוזת (לדוגמה, "$19.99"), בעוד ששירות אחר מצפה לו כסוג מספרי (לדוגמה, 19.99). פער קטן לכאורה זה עלול להוביל לכשלים קטסטרופליים, שיבוש נתונים וזמן השבתה משמעותי, במיוחד כאשר פועלים באזורי זמן וסביבות רגולטוריות שונות.
בטיחות סוג בהזרמת אירועים פירושה הבטחה שמבנה וסוגי הנתונים של הודעות מוחלפות עומדים בחוזה מוגדר מראש. חוזה זה, המכונה לעתים קרובות סכמה, משמש כתוכנית עבור הנתונים. כאשר יצרן מפרסם אירוע, עליו להתאים לסכמה. כאשר צרכן נרשם, הוא מצפה לנתונים התואמים לסכמה זו. זה מבטיח:
- תקינות נתונים: מונע מנתונים פגומים או שגויים להתפשט במערכת, ומפחית את הסיכון של שיבוש נתונים ושגיאות לוגיות עסקיות.
 - התנהגות צפויה: צרכנים יכולים להסתמך על המבנה והסוגים של אירועים נכנסים, ולפשט את היישום שלהם ולהפחית את הצורך באימות זמן ריצה נרחב.
 - איתור באגים ופתרון תקלות קלים יותר: כאשר מתעוררת בעיה, מפתחים יכולים לאתר במהירות האם הבעיה טמונה בהקפדה של היצרן על הסכמה או בפרשנות הצרכן.
 - אבולוציה פשוטה: עם סכמה מוגדרת היטב ומערכת סוגים חזקה, פיתוח מבני האירועים שלך לאורך זמן (לדוגמה, הוספת שדות חדשים, שינוי סוגי נתונים) הופך לתהליך ניתן לניהול, וממזער שינויים שוברים עבור צרכנים.
 - יכולת פעולה הדדית: בעולם גלובלי עם צוותי פיתוח מגוונים ומערכות טכנולוגיות, בטיחות סוג מבטיחה ששירותים שנבנו בשפות ומסגרות שונות עדיין יכולים לתקשר ביעילות.
 
אתגרים נפוצים ביישום סוג הזרמת אירועים
למרות היתרונות הברורים, השגת בטיחות סוג אמיתית בהזרמת אירועים אינה חפה ממכשולים. מספר אתגרים מתעוררים בדרך כלל, במיוחד במערכות גדולות, מבוזרות ומתפתחות:
1. פורמטים של נתונים דינמיים או בעלי הקלדה רופפת
פורמטים כמו JSON, למרות שהם נמצאים בכל מקום וקריאים לאדם, הם גמישים מטבעם. גמישות זו יכולה להיות חרב פיפיות. ללא אכיפת סכמה מפורשת, קל לשלוח נתונים עם סוגים לא צפויים או שדות חסרים. לדוגמה, שדה quantity שמיועד להיות מספר שלם עשוי להישלח כמחרוזת או מספר נקודה צפה, מה שיוביל לשגיאות ניתוח או חישובים שגויים.
2. ניהול אבולוציית סכמה
יישומים הם לעתים רחוקות סטטיים. ככל שדרישות עסקיות משתנות, סכמות אירועים חייבות להתפתח. האתגר טמון בעדכון סכמות אלה מבלי לשבור צרכנים קיימים. יצרן עשוי להוסיף שדה חדש ואופציונלי, או שצרכן עשוי לדרוש ששדה אופציונלי בעבר יהיה חובה. ניהול שינויים אלה בחן מצריך תכנון קפדני וכלים התומכים בתאימות לאחור וקדימה.
3. הטרוגניות של שפה ופלטפורמה
ארגונים גלובליים מעסיקים לעתים קרובות מערכות טכנולוגיות מגוונות. שירותים עשויים להיכתב ב-Java, Python, Go, Node.js או .NET. הבטחה שהגדרות סוגים יובנו ויוחלו באופן עקבי על פני שפות ופלטפורמות שונות אלה היא משימה משמעותית. פורמט הגדרת סכמה נפוץ ואגנוסטי לשפה הוא חיוני.
4. מדרגיות ותקורה של ביצועים
יישום בדיקת סוגים ואימות סכמה יכול להכניס תקורה של ביצועים. פורמט הסדרתיזציה ומנגנוני האימות הנבחרים חייבים להיות יעילים מספיק כדי להתמודד עם זרמי אירועים בעלי תפוקה גבוהה מבלי להפוך לצוואר בקבוק. זה קריטי במיוחד לעיבוד נתונים בזמן אמת או כמעט בזמן אמת.
5. בעלות ושליטה מבוזרות על נתונים
בארכיטקטורת מיקרו-שירותים, צוותים שונים מחזיקים לעתים קרובות בבעלות על שירותים שונים, ובהרחבה, על האירועים שהם מייצרים. ביסוס גישה אחידה להגדרת סכמה, ניהול ושליטה על פני צוותים מבוזרים אלה יכול להיות קשה. ללא בעלות ותהליכים ברורים, סחף סכמות ואי עקביות סביר להניח.
6. היעדר מנגנוני אכיפה סטנדרטיים
בעוד שבוררי הודעות רבים מציעים אימות בסיסי, לעתים קרובות חסרים להם מנגנונים מובנים וחזקים לאכיפת כללי סכמה מורכבים או לניהול גרסאות סכמה ביעילות. זה מטיל נטל גדול יותר על מפתחי יישומים ליישם בדיקות אלה בעצמם.
אסטרטגיות וטכנולוגיות להזרמת אירועים מאובטחת טיפוס
כדי להתגבר על אתגרים אלה, שילוב של אסטרטגיות מוגדרות היטב והטכנולוגיות הנכונות הוא חיוני. הליבה של הזרמת אירועים מאובטחת טיפוס טמונה בהגדרה ואכיפה של חוזי נתונים (סכמות) בשלבים שונים של מחזור החיים של האירוע.
1. שפות להגדרת סכמה
הבסיס לבטיחות סוג הוא שפת הגדרת סכמה חזקה שהיא גם אקספרסיבית וגם אגנוסטית לפלטפורמה. קיימות מספר אפשרויות פופולריות, שלכל אחת מהן חוזקות משלה:
- Apache Avro: מערכת סדרתיזציה של נתונים מבוססת שורות המשתמשת ב-JSON להגדרת סוגי נתונים ופרוטוקולים. הוא מיועד לייצוג נתונים קומפקטי וסדרתיזציה יעילה. סכמות Avro מוגדרות באופן סטטי ומתאימות היטב למבני נתונים מתפתחים עם התמיכה שלהן באבולוציית סכמה. הוא נמצא בשימוש נרחב עם Apache Kafka.
    
דוגמה לסכמת Avro (product_created.avsc):
{ "type": "record", "name": "ProductCreated", "namespace": "com.example.events", "fields": [ {"name": "product_id", "type": "string"}, {"name": "name", "type": "string"}, {"name": "price", "type": "double"}, {"name": "stock_count", "type": "int", "default": 0}, {"name": "timestamp", "type": "long", "logicalType": "timestamp-millis"} ] } - Protocol Buffers (Protobuf): Protobuf, שפותח על ידי גוגל, הוא מנגנון ניטרלי לשפה, ניטרלי לפלטפורמה וניתן להרחבה לסדרתיזציה של נתונים מובנים. הוא יעיל ביותר, קומפקטי ומהיר. סכמות מוגדרות בקבצי `.proto`. החוזק של Protobuf טמון בביצועים ובאכיפת חוזים חזקה.
    
דוגמה לסכמת Protobuf (product_event.proto):
syntax = "proto3"; package com.example.events; message ProductCreated { string product_id = 1; string name = 2; double price = 3; optional int32 stock_count = 4 [default = 0]; int64 timestamp = 5; } - JSON Schema: אוצר מילים המאפשר לך להוסיף הערות ולאמת מסמכי JSON. הוא מצוין להגדרת המבנה, התוכן והסמנטיקה של נתוני JSON. למרות שהוא לא ממוטב ביצועים כמו Avro או Protobuf עבור סדרתיזציה גולמית, הוא גמיש מאוד ומובן באופן נרחב בשל הפופולריות של JSON.
    
דוגמה לסכמת JSON (product_created.schema.json):
{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "ProductCreated", "description": "Event indicating a new product has been created.", "type": "object", "properties": { "product_id": {"type": "string", "description": "Unique identifier for the product."} , "name": {"type": "string", "description": "Name of the product."} , "price": {"type": "number", "format": "double", "description": "Current price of the product."} , "stock_count": {"type": "integer", "default": 0, "description": "Number of items in stock."} , "timestamp": {"type": "integer", "format": "int64", "description": "Timestamp in milliseconds since epoch."} }, "required": ["product_id", "name", "price", "timestamp"] } 
2. פורמטים של סדרתיזציה
לאחר הגדרת סכמה, אתה זקוק לדרך לסדר נתונים בהתאם לסכמה זו. הבחירה בפורמט סדרתיזציה משפיעה ישירות על ביצועים, גודל ותאימות:
- פורמטים בינאריים (Avro, Protobuf): פורמטים אלה מייצרים נתונים בינאריים קומפקטיים, מה שמוביל לגדלי הודעות קטנים יותר וסדרתיזציה/הפחתה מהירה יותר. זה חיוני לתרחישים של תפוקה גבוהה ולמזעור רוחב פס רשת, במיוחד עבור זרימות נתונים גלובליות.
    
יתרון: ביצועים גבוהים, טביעת רגל קטנה. אתגר: לא קריא לאדם ללא כלים ספציפיים.
 - פורמטים טקסטואליים (JSON): למרות שהם פחות יעילים מבחינת גודל ומהירות בהשוואה לפורמטים בינאריים, JSON קריא לאדם ונתמך באופן נרחב על פני פלטפורמות ושפות שונות. כאשר משתמשים בו עם JSON Schema, הוא עדיין יכול לספק ערבויות סוג חזקות.
    
יתרון: קריא לאדם, תמיכה בכל מקום. אתגר: גודל הודעה גדול יותר, סדרתיזציה/הפחתה איטית יותר.
 
3. רישומי סכמה
רישום סכמה הוא מאגר מרכזי לאחסון, ניהול וגרסאות של סכמות. הוא משמש כמקור יחיד של אמת עבור כל הסכמות המשמשות בארגון. הפונקציות העיקריות של רישום סכמה כוללות:
- אחסון סכמה: משמר את כל הסכמות המוגדרות.
 - גרסאות סכמה: מנהל גרסאות שונות של סכמה, ומאפשר אבולוציה חן.
 - בדיקות תאימות סכמה: אוכף כללי תאימות (לאחור, קדימה, מלא) כדי להבטיח שעדכוני סכמה לא ישברו צרכנים או יצרנים קיימים.
 - גילוי סכמה: מאפשר ליצרנים ולצרכנים לגלות את גרסת הסכמה הנכונה לנושא או אירוע נתון.
 
פתרונות רישום סכמה פופולריים כוללים:
- Confluent Schema Registry: משתלב היטב עם Apache Kafka ותומך ב-Avro, JSON Schema ו-Protobuf. זהו תקן דה פקטו במערכת האקולוגית של Kafka.
 - Apicurio Registry: רישום קוד פתוח התומך בפורמטים מרובים, כולל Avro, Protobuf, JSON Schema ו-OpenAPI.
 
4. יכולות של בורר הודעות ופלטפורמת הזרמת אירועים
הבחירה בבורר הודעות או בפלטפורמת הזרמת אירועים ממלאת גם היא תפקיד. בעוד שפלטפורמות רבות אינן אוכפות סכמות בעצמן, הן יכולות להשתלב עם כלים חיצוניים כמו רישומי סכמה או לספק ווי אימות בסיסיים.
- Apache Kafka: פלטפורמת הזרמת אירועים מבוזרת. Kafka עצמה אינה אוכפת סכמות אך משתלבת בצורה חלקה עם רישומי סכמה לבטיחות סוג. המדרגיות והסובלנות לתקלות שלו הופכות אותו לאידיאלי עבור צינורות נתונים גלובליים.
 - RabbitMQ: בורר הודעות פופולרי התומך בפרוטוקולים שונים. למרות שהוא לא מודע לסכמה באופן טבעי, ניתן לשלב אותו עם שכבות אימות.
 - Amazon Kinesis: שירות AWS מנוהל להזרמת נתונים בזמן אמת. בדומה ל-Kafka, הוא דורש לעתים קרובות שילוב עם כלי ניהול סכמות חיצוניים.
 - Google Cloud Pub/Sub: שירות העברת הודעות בזמן אמת בניהול מלא. הוא מספק הזמנת הודעות והכפלתן, אך מסתמך על לוגיקה ברמת היישום או כלים חיצוניים לאכיפת סכמה.
 
5. ספריות ומסגרות בצד הלקוח
לרוב פורמטי הסדרתיזציה (Avro, Protobuf) מגיעים עם כלי יצירת קוד. מפתחים יכולים ליצור מחלקות ספציפיות לשפה מקבצי ה-`.avsc` או `.proto` שלהם. מחלקות שנוצרו אלה מספקות בדיקת סוגים בזמן קומפילציה, ומבטיחות שיצרנים יוצרים אירועים במבנה הנכון וצרכנים מצפים לנתונים בפורמט מוגדר היטב.
דוגמה (מושגית - Java עם Avro):
            // Generated Avro class
ProductCreated event = new ProductCreated();
event.setProductId("prod-123");
event.setName("Global Widget");
event.setPrice(25.50);
// event.setStockCount(100); // This field has a default value
// Sending the event to Kafka
kafkaProducer.send(new ProducerRecord<>(topic, event.getProductId(), event));
            
          
        בעת שימוש ב-JSON Schema, קיימות ספריות ברוב השפות כדי לאמת מטעני JSON מול סכמה נתונה לפני שליחה או לאחר קבלה.
יישום הזרמת אירועים מאובטחת טיפוס בפועל
יישום הזרמת אירועים מאובטחת טיפוס כרוך בגישה שיטתית הנוגעת לפיתוח, תפעול ושליטה.
שלב 1: הגדר את חוזי האירועים שלך (סכמות)
לפני כתיבת קוד כלשהו, הגדר באופן שיתופי את המבנה והסוגים של האירועים שלך. בחר שפת הגדרת סכמה (Avro, Protobuf, JSON Schema) המתאימה ביותר לצרכים שלך בנוגע לביצועים, קריאות ותאימות למערכת האקולוגית. ודא מוסכמות שמות ותיעוד ברורים עבור כל סוג אירוע והשדות שלו.
שלב 2: בחר רישום סכמה
יישם רישום סכמה כדי לרכז את ניהול הסכמה. זה חיוני לעקביות, גרסאות ובדיקות תאימות בין הצוותים הגלובליים שלך.
שלב 3: שלב רישום סכמה עם בורר ההודעות שלך
הגדר את בורר ההודעות או את פלטפורמת הזרמת האירועים שלך כדי ליצור אינטראקציה עם רישום הסכמה. עבור Kafka, זה כרוך בדרך כלל בהגדרה של סדרתיזציה והפחתה המביאים סכמות מהרישום. יצרנים ישתמשו בסדרתיזציה כדי לקודד הודעות בהתאם לסכמה הרשומה, וצרכנים ישתמשו בהפחתה כדי לפענח הודעות.
שלב 4: יישם יצרנים עם אכיפת סכמה
יש לעצב יצרנים כך:
- צור נתונים: השתמש במחלקות שנוצרו (מ-Avro/Protobuf) או בנה אובייקטי נתונים התואמים לסכמה.
 - סדר: השתמש בסדר הסדרתי המוגדר כדי להמיר את אובייקט הנתונים לפורמט הבינארי או הטקסטואלי הנבחר.
 - רשום סכמה (אם חדשה): לפני פרסום האירוע הראשון של גרסת סכמה חדשה, רשום אותו ברישום הסכמה. הרישום יבדוק תאימות.
 - פרסם: שלח את האירוע הסדרתי לבורר ההודעות.
 
שלב 5: יישם צרכנים עם מודעות לסכמה
יש לעצב צרכנים כך:
- צרכו: קבלו את האירוע הגולמי הסדרתי מבורר ההודעות.
 - צמצמו: השתמשו בהפחתה המוגדרת כדי לשחזר את אובייקט הנתונים בהתבסס על הסכמה. הפחתה תביא את הסכמה המתאימה מהרישום.
 - עבדו: עבדו עם אובייקט הנתונים בעל הקלדה חזקה, ותיהנו מבדיקת סוג בזמן קומפילציה או בזמן ריצה.
 
שלב 6: קבע מדיניות אבולוציית סכמה
הגדר כללים ברורים לאבולוציית סכמה. אסטרטגיות נפוצות כוללות:
- תאימות לאחור: צרכנים חדשים יכולים לקרוא נתונים המיוצרים עם סכמות ישנות יותר. זה מושג על ידי הוספת שדות אופציונליים או שימוש בערכי ברירת מחדל.
 - תאימות קדימה: צרכנים ישנים יכולים לקרוא נתונים המיוצרים עם סכמות חדשות יותר. זה מושג על ידי התעלמות משדות חדשים.
 - תאימות מלאה: מבטיחה תאימות לאחור וקדימה.
 
יש להגדיר את רישום הסכמה שלך כדי לאכוף כללי תאימות אלה. בדוק תמיד את אבולוציית הסכמה ביסודיות בסביבות ביניים.
שלב 7: ניטור והתראה
יישם ניטור חזק לשגיאות הקשורות לסכמה. יש להפעיל התראות עבור:
- כשלים באימות סכמה.
 - בעיות חיבור לרישום סכמה.
 - שינויי סכמה או אי תאימויות בלתי צפויים.
 
שיקולים גלובליים להזרמת אירועים מאובטחת טיפוס
בעת יישום בוררי הודעות מאובטחי טיפוס בהקשר גלובלי, מספר גורמים ספציפיים נכנסים לתמונה:
- השהיה: ודא שמנגנוני רישום הסכמה והסדרתיזציה שלך יעילים מספיק כדי להתמודד עם השהיות רשת גלובליות. שקול לפרוס רישומי סכמה במספר אזורים או להשתמש במטמון מבוזר.
 - מגורים ותאימות נתונים: הבן היכן נתוני האירועים שלך מעובדים ומאוחסנים. בעוד ש*סכמות* אירועים הם חוזים, ייתכן שמ*טעני* האירועים בפועל יצטרכו לעמוד בתקנות מגורים אזוריות של נתונים (לדוגמה, GDPR באירופה). האופי מאובטח הטיפוס של האירועים שלך יכול לעזור בזיהוי וניהול ברור של נתונים רגישים.
 - אזורי זמן וטיפול בחותמות זמן: ודא טיפול עקבי בחותמות זמן בין אזורי זמן שונים. שימוש בפורמטים סטנדרטיים כמו ISO 8601 או מילישניות עידן עם סוגים לוגיים ברורים (לדוגמה, `timestamp-millis` ב-Avro) הוא חיוני.
 - מטבע ויחידות מידה: היה מפורש לגבי סמלי מטבע ויחידות מידה בתוך הסכמות שלך. לדוגמה, במקום רק שדה 
price, שקול מבנה כמו{ "amount": 19.99, "currency": "USD" }. זה מונע עמימות בעת התמודדות עם עסקאות בינלאומיות. - נתונים רב-לשוניים: אם האירועים שלך מכילים נתוני טקסט שצריכים להיות רב-לשוניים, הגדר כיצד יטופלו קודי שפה (לדוגמה, שדות נפרדים לשפות שונות, או שדה מובנה כמו `localized_name: { "en": "Product", "es": "Producto" }`).
 - שיתוף פעולה ותיעוד צוות: עם צוותי פיתוח מבוזרים גלובלית, שמירה על תיעוד עקבי עבור סכמות אירועים ודפוסי שימוש היא חיונית. רישום סכמה מתוחזק היטב עם תיאורים ודוגמאות ברורים יכול לסייע משמעותית בשיתוף פעולה.
 
קטעי מחקר מקרה (מושגיים)
קמעונאי גלובלי: צינור לעיבוד הזמנות
קמעונאי בינלאומי גדול משתמש ב-Kafka לעיבוד ההזמנות שלו. אירועים כמו OrderPlaced, PaymentProcessed ו-ShipmentInitiated הם קריטיים. הם משתמשים ב-Avro עם Confluent Schema Registry. כאשר מתווסף אזור חדש, ומוצג מטבע חדש (לדוגמה, JPY), סכמת האירוע OrderPlaced צריכה להתפתח. על ידי שימוש בסכמה עם מבנה כמו { "amount": 10000, "currency": "JPY" } והבטחת תאימות לאחור, שירותי עיבוד הזמנות קיימים יכולים להמשיך לתפקד ללא עדכונים מיידיים. רישום הסכמה מונע פרסום אירועים לא תואמים, ומבטיח שכל הצינור יישאר חזק.
חברת פינטק: אירועים טרנזקציוניים
חברת פינטק גלובלית מעבדת מיליוני עסקאות פיננסיות מדי יום. בטיחות סוג אינה ניתנת למשא ומתן. הם ממנפים את Protobuf עבור הביצועים והייצוג הקומפקטי שלו בזרמי האירועים שלהם. אירועים כמו TransactionCreated ו-BalanceUpdated הם רגישים. שימוש ב-Protobuf עם רישום סכמה עוזר להבטיח שסכומי עסקאות, מספרי חשבונות וחותמות זמן תמיד מנותחים כראוי, ומונעים שגיאות יקרות והפרות רגולטוריות. יצירת הקוד מקבצי `.proto` מספקת ערבויות חזקות בזמן קומפילציה למפתחים העובדים בשפות שונות במשרדים הבינלאומיים שלהם.
מסקנה
בעולם מקושר ומבוזר יותר ויותר, המהימנות של תקשורת בין שירותים היא אבן יסוד של פיתוח יישומים מוצלח. בוררי הודעות מאובטחי טיפוס ויישום סוג הזרמת אירועים חזק אינם רק טכניקות מתקדמות; הם דרישות בסיסיות לבניית מערכות גמישות, ניתנות להרחבה וקלות לתחזוקה בקנה מידה גלובלי.
על ידי אימוץ שפות להגדרת סכמה, מינוף רישומי סכמה והקפדה על אסטרטגיות אבולוציית סכמה ממושמעות, ארגונים יכולים להפחית באופן משמעותי את הסיכונים הקשורים לתקינות נתונים וכשלים במערכת. גישה יזומה זו להגדרה ואכיפה של חוזי נתונים מבטיחה שהמערכות המבוזרות שלך יוכלו לתקשר בצורה צפויה ומהימנה, ללא קשר להפצה הגיאוגרפית של השירותים שלך או למגוון צוותי הפיתוח שלך. השקעה בבטיחות סוג היא השקעה ביציבות והצלחה ארוכת הטווח של היישומים הגלובליים שלך.